import { useCallback, useEffect, useRef, useState } from 'react';
import {
  ActivityIndicator,
  Modal,
  Pressable,
  RefreshControl,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  View,
  useWindowDimensions,
  Animated,
} from 'react-native';
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { Image } from 'expo-image';
import { useRouter } from 'expo-router';
import Ionicons from '@expo/vector-icons/Ionicons';
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';

import { useDebouncedValue } from '@/hooks/use-debounced-value';
import { apiRequestWithMeta } from '@/utils/api';
import { resolveAssetUrl, WECHAT_QR_URL } from '@/constants/config';
import wechatQrPlaceholder from '@/assets/images/partial-react-logo.png';

const HERO_VISUAL =
  'https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?auto=format&fit=crop&w=960&q=80';

type ApiAsset = {
  id: number;
  preview_url?: string;
  thumb_url?: string;
  original_url?: string;
};

type ApiProductImage = {
  id: number;
  sort_order: number;
  is_preview?: boolean;
  asset?: ApiAsset | null;
};

type ApiProduct = {
  id: number;
  title: string;
  type: string;
  description: string;
  price: number;
  promo_price?: number;
  promo_expires_at?: string;
  cover_asset?: ApiAsset | null;
  images?: ApiProductImage[];
};

type ProductCard = {
  id: number;
  title: string;
  type: string;
  description: string;
  price: string;
  heroImage: string;
  promo?: boolean;
  promoPrice?: string;
};

const PAGE_SIZE = 30;

const formatCurrency = (value: number) => {
  if (!Number.isFinite(value)) {
    return '¥0.00';
  }
  return `¥${value.toFixed(2)}`;
};

const mapProduct = (item: ApiProduct): ProductCard => {
  const heroCandidate =
    item.cover_asset?.preview_url ||
    item.cover_asset?.thumb_url ||
    item.images?.[0]?.asset?.preview_url ||
    item.images?.[0]?.asset?.thumb_url ||
    '';
  const heroImage = resolveAssetUrl(heroCandidate) || HERO_VISUAL;
  return {
    id: item.id,
    title: item.title,
    type: item.type,
    description: item.description ?? '',
    price: formatCurrency(item.price ?? 0),
    heroImage,
    promo: typeof (item as any).promo_price === 'number',
    promoPrice: typeof (item as any).promo_price === 'number'
      ? formatCurrency((item as any).promo_price as number)
      : undefined,
  };
};

export default function HomeScreen() {
  const router = useRouter();
  const tabBarHeight = useBottomTabBarHeight();
  const { bottom: safeBottom } = useSafeAreaInsets();
  const fabBottom = Math.max(tabBarHeight + 12, safeBottom + 24, 24);
  const [query, setQuery] = useState('');
  const debouncedQuery = useDebouncedValue(query, 400);
  const { width } = useWindowDimensions();
  const isCompact = width < 768;
  const isTablet = width >= 768 && width < 1200;

  const [products, setProducts] = useState<ProductCard[]>([]);
  const [isLoading, setLoading] = useState(true);
  const [isRefreshing, setRefreshing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [isQrVisible, setQrVisible] = useState(false);
  const wechatQrUrl = WECHAT_QR_URL ? resolveAssetUrl(WECHAT_QR_URL) : '';
  const wechatQrSource = wechatQrUrl ? { uri: wechatQrUrl } : wechatQrPlaceholder;

  // promo badge pulse animation (lightweight, shared)
  const promoPulse = useRef(new Animated.Value(1));
  useEffect(() => {
    const a = Animated.loop(
      Animated.sequence([
        Animated.timing(promoPulse.current, { toValue: 0.6, duration: 900, useNativeDriver: true }),
        Animated.timing(promoPulse.current, { toValue: 1, duration: 900, useNativeDriver: true }),
      ]),
    );
    a.start();
    return () => a.stop();
  }, []);

  const CardImage = ({ uri }: { uri: string }) => {
    const [failed, setFailed] = useState(false);
    const src = failed || !uri
      ? require('../../assets/images/partial-react-logo.png')
      : { uri } as const;
    return (
      <Image
        source={src}
        onError={() => setFailed(true)}
        style={styles.cardImage}
        contentFit="cover"
        transition={240}
        cachePolicy="memory-disk"
      />
    );
  };

  const loadProducts = useCallback(
    async (keyword: string, mode: 'initial' | 'refresh' = 'initial') => {
      if (mode === 'refresh') {
        setRefreshing(true);
      } else {
        setLoading(true);
      }

      try {
        const { data } = await apiRequestWithMeta<ApiProduct[], unknown>('/products', {
          query: {
            page: 1,
            page_size: PAGE_SIZE,
            search: keyword || undefined,
            published: true,
          },
        });

        const normalized = (data ?? []).map(mapProduct);
        setProducts(normalized);
        setError(null);
      } catch (err) {
        setProducts([]);
        setError(err instanceof Error ? err.message : '商品加载失败，请稍后重试');
      } finally {
        if (mode === 'refresh') {
          setRefreshing(false);
        }
        setLoading(false);
      }
    },
    [],
  );

  useEffect(() => {
    loadProducts(debouncedQuery || '');
  }, [debouncedQuery, loadProducts]);

  const handleRefresh = useCallback(() => {
    loadProducts(debouncedQuery || '', 'refresh');
  }, [debouncedQuery, loadProducts]);

  const handleOpenCustomization = useCallback(() => {
    setQrVisible(true);
  }, []);

  return (
    <SafeAreaView style={styles.safeArea}>
      <ScrollView
        style={styles.scroll}
        contentContainerStyle={styles.container}
        showsVerticalScrollIndicator={false}
        refreshControl={<RefreshControl refreshing={isRefreshing} onRefresh={handleRefresh} />}
      >
        <View style={styles.header}>
          <View style={styles.logo}>
            <Text style={styles.logoText}>PS+</Text>
          </View>
          <Text style={styles.headerTheme}>Portrait Inspiration Guide</Text>
        </View>

        <View style={[styles.hero, isCompact && styles.heroStacked]}>
          <View style={styles.heroContent}>
            <Text style={styles.heroOverline}>精选套系</Text>
            <Text style={styles.heroTitle}>一站式创意人像服务</Text>

            <View style={[styles.searchSurface, isCompact && styles.searchSurfaceCompact]}>
              <TextInput
                style={[styles.searchInput, isCompact && styles.searchInputCompact]}
                placeholder="Try keywords: portrait, studio, travel"
                placeholderTextColor="rgba(64,48,72,0.55)"
                value={query}
                onChangeText={setQuery}
                returnKeyType="search"
              />
            </View>

            <View style={[styles.heroTags, isCompact && styles.heroTagsWrap]}>
              <Text style={styles.heroTag}>新品首发</Text>
              <Text style={styles.heroTag}>旅拍电商</Text>
              <Text style={styles.heroTag}>直播逛拍</Text>
            </View>
          </View>

          <View style={[styles.heroVisual, isCompact && styles.heroVisualWide]}>
            <Image
              source={{ uri: HERO_VISUAL }}
              style={[styles.heroImage, isCompact && styles.heroImageWide]}
              contentFit="cover"
              transition={300}
              cachePolicy="memory-disk"
            />
            <View style={styles.heroBadge}>
              <Text style={styles.heroBadgeTitle}>2025 年度推荐</Text>
              <Text style={styles.heroBadgeSubtitle}>Light &amp; Motion</Text>
            </View>
          </View>
        </View>
        <View style={styles.section}>
          <View style={styles.sectionHeader}>
            <Text style={styles.sectionOverline}>热门推荐</Text>
            <Text style={styles.sectionTitle}>当下高口碑拍摄方案</Text>
            <Text style={styles.sectionDescription}>
              覆盖品牌发布、社媒营销与线下活动，全流程拍摄到内容发布支持。
            </Text>
          </View>

          {isLoading ? (
            <View style={styles.stateBox}>
              <ActivityIndicator color="#ff8fb1" />
              <Text style={styles.stateText}>正在加载商品，请稍后…</Text>
            </View>
          ) : error ? (
            <View style={[styles.stateBox, styles.stateBoxError]}>
              <Text style={[styles.stateText, styles.stateTextDanger]}>{error}</Text>
              <Pressable style={styles.retryButton} onPress={() => loadProducts(debouncedQuery || '')}>
                <Text style={styles.retryButtonText}>重新加载</Text>
              </Pressable>
            </View>
          ) : products.length > 0 ? (
            <View style={[styles.cardGrid, isCompact && styles.cardGridStacked]}>
              {products.map((product) => (
                <Pressable
                  key={product.id}
                  onPress={() =>
                    router.push({ pathname: '/c/product/[id]', params: { id: String(product.id) } })
                  }
                  style={[
                    styles.card,
                    isCompact ? styles.cardFull : isTablet ? styles.cardThird : undefined,
                  ]}
                >
                  <View style={styles.mediaBox}>
                    <CardImage uri={product.heroImage} />
                    {product.promo ? (
                      <Animated.View style={[styles.promoBadge, { opacity: promoPulse.current }]}>
                        <Text style={styles.promoBadgeText}>限时</Text>
                      </Animated.View>
                    ) : null}
                    <View style={styles.priceBadge}>
                      {product.promo && product.promoPrice ? (
                        <>
                          <Text style={styles.pricePromoText}>{product.promoPrice}</Text>
                          <Text style={styles.priceOriginText}>{product.price}</Text>
                        </>
                      ) : (
                        <Text style={styles.priceBadgeText}>{product.price}</Text>
                      )}
                    </View>
                  </View>
                  <View style={styles.cardBody}>
                    <Text style={styles.cardTitle} numberOfLines={1}>
                      {product.title}
                    </Text>
                    <Text style={styles.cardType} numberOfLines={1}>
                      {product.type}
                    </Text>
                    <Text style={styles.cardDescription} numberOfLines={1}>
                      {product.description}
                    </Text>
                  </View>
                </Pressable>
              ))}
            </View>
          ) : (
            <Text style={styles.emptyState}>暂未找到匹配的套系，换个关键词再试试吧。</Text>
          )}
        </View>

        <View style={styles.section}>
          <View style={styles.sectionHeader}>
            <Text style={styles.sectionOverline}>灵感内容</Text>
            <Text style={styles.sectionTitle}>质感主题与拍摄亮点</Text>
          </View>
          <View style={[styles.heroTags, styles.heroTagsWrap]}>
            <Text style={styles.heroTag}>室内套系</Text>
            <Text style={styles.heroTag}>心理肖像</Text>
            <Text style={styles.heroTag}>新品发布</Text>
            <Text style={styles.heroTag}>线下活动</Text>
            <Text style={styles.heroTag}>社媒短视频</Text>
          </View>
        </View>

        <View style={styles.footer}>
          <Text style={styles.footerText}>© 2025 PhotoSales Plus. 影像品牌灵感指南</Text>
        </View>
      </ScrollView>

      <View pointerEvents="box-none" style={[styles.fabContainer, { bottom: fabBottom }]}>
        <Pressable
          accessibilityRole="button"
          accessibilityLabel="打开微信定制二维码"
          style={styles.fabButton}
          onPress={handleOpenCustomization}
        >
          <Ionicons
            name="qr-code-outline"
            size={10}
            color="#fff"
            style={styles.fabIcon}
          />
          <Text style={styles.fabButtonText}>定</Text>
          <Text style={styles.fabButtonText}>制</Text>
        </Pressable>
      </View>

      {isQrVisible ? (
        <Modal
          transparent
          animationType="fade"
          visible={isQrVisible}
          onRequestClose={() => setQrVisible(false)}
        >
          <View style={styles.customOverlay}>
            <Pressable style={styles.customDismiss} onPress={() => setQrVisible(false)} />
            <View style={styles.customModal}>
              <Text style={styles.customModalTitle}>扫码添加微信</Text>
              <Image
                source={wechatQrSource}
                style={styles.customQr}
                contentFit="contain"
              />
              <Pressable style={styles.customClose} onPress={() => setQrVisible(false)}>
                <Text style={styles.customCloseText}>关闭</Text>
              </Pressable>
            </View>
          </View>
        </Modal>
      ) : null}
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
    backgroundColor: '#fff7fb',
  },
  scroll: {
    flex: 1,
  },
  container: {
    paddingHorizontal: 24,
    paddingVertical: 28,
    gap: 36,
  },
  customOverlay: {
    flex: 1,
    justifyContent: 'flex-end',
    backgroundColor: 'rgba(0,0,0,0.4)',
  },
  customDismiss: {
    flex: 1,
  },
  customModal: {
    paddingTop: 28,
    paddingBottom: 32,
    paddingHorizontal: 24,
    borderTopLeftRadius: 28,
    borderTopRightRadius: 28,
    backgroundColor: '#fff',
    alignItems: 'center',
    gap: 16,
  },
  customModalTitle: {
    fontSize: 18,
    fontWeight: '700',
    color: '#2f1f2b',
  },
  customModalSubtitle: {
    fontSize: 13,
    color: '#6a566a',
    lineHeight: 20,
    textAlign: 'center',
  },
  customQr: {
    width: 220,
    height: 220,
    borderRadius: 18,
    backgroundColor: '#f4e9f0',
  },
  customClose: {
    marginTop: 4,
    paddingHorizontal: 24,
    paddingVertical: 12,
    borderRadius: 999,
    backgroundColor: '#ff8fb1',
  },
  customCloseText: {
    fontSize: 14,
    fontWeight: '600',
    color: 'white',
  },
  fabContainer: {
    position: 'absolute',
    right: 0,
    alignItems: 'flex-start',
    zIndex: 40,
    elevation: 40,
  },
  fabButton: {
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center',
    width: 18,
    minHeight: 50,
    // paddingVertical: 2,
    // paddingHorizontal: 1,
    backgroundColor: '#ff6fa0',
    elevation: 12,
    shadowColor: '#ff6fa0'
  },
  fabIcon: {
    alignSelf: 'center',
  },
  fabButtonText: {
    textAlign: 'center',
    fontSize: 10,
    color: '#fff',
  },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  logo: {
    width: 44,
    height: 44,
    borderRadius: 16,
    backgroundColor: '#ff8fb1',
    justifyContent: 'center',
    alignItems: 'center',
    shadowColor: '#ffb7c5',
    shadowOffset: { width: 0, height: 8 },
    shadowOpacity: 0.3,
    shadowRadius: 12,
    elevation: 4,
  },
  logoText: {
    color: '#2f1f2b',
    fontSize: 18,
    fontWeight: '700',
    letterSpacing: 0.6,
  },
  headerTheme: {
    fontSize: 14,
    color: '#6a566a',
    fontWeight: '600',
  },
  hero: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    gap: 24,
    padding: 28,
    borderRadius: 32,
    backgroundColor: '#ffeafb',
    borderWidth: 1,
    borderColor: 'rgba(255,143,177,0.18)',
    shadowColor: '#ffd2e4',
    shadowOffset: { width: 0, height: 16 },
    shadowOpacity: 0.25,
    shadowRadius: 28,
    elevation: 6,
  },
  heroStacked: {
    flexDirection: 'column',
    padding: 20,
  },
  heroContent: {
    flex: 1,
    gap: 18,
  },
  heroOverline: {
    fontSize: 12,
    letterSpacing: 2,
    textTransform: 'uppercase',
    color: '#d66a8a',
  },
  heroTitle: {
    fontSize: 28,
    fontWeight: '700',
    color: '#2f1f2b',
    lineHeight: 34,
  },
  searchSurface: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 12,
    backgroundColor: '#fff',
    borderRadius: 22,
    padding: 10,
    borderWidth: 1,
    borderColor: 'rgba(220,195,208,0.4)',
  },
  searchSurfaceCompact: {
    flexDirection: 'column',
    alignItems: 'stretch',
  },
  searchInput: {
    flex: 1,
    height: 44,
    borderRadius: 16,
    paddingHorizontal: 16,
    backgroundColor: '#fff',
    color: '#2f1f2b',
    fontSize: 14,
  },
  searchInputCompact: {
    width: '100%',
  },
  heroTags: {
    flexDirection: 'row',
    gap: 10,
  },
  heroTagsWrap: {
    flexWrap: 'wrap',
  },
  heroTag: {
    paddingHorizontal: 14,
    paddingVertical: 6,
    borderRadius: 999,
    backgroundColor: 'rgba(255,143,177,0.16)',
    color: '#d66a8a',
    fontSize: 12,
    fontWeight: '600',
  },
  heroVisual: {
    width: 320,
    height: 220,
    borderRadius: 28,
    overflow: 'hidden',
    shadowColor: '#ffb7d1',
    shadowOffset: { width: 0, height: 12 },
    shadowOpacity: 0.25,
    shadowRadius: 22,
    elevation: 6,
  },
  heroVisualWide: {
    width: '100%',
    height: 220,
  },
  heroImage: {
    width: '100%',
    height: '100%',
  },
  heroImageWide: {
    borderRadius: 24,
  },
  heroBadge: {
    position: 'absolute',
    bottom: 16,
    left: 16,
    paddingHorizontal: 14,
    paddingVertical: 8,
    borderRadius: 14,
    backgroundColor: 'rgba(0,0,0,0.55)',
  },
  heroBadgeTitle: {
    fontSize: 13,
    fontWeight: '700',
    color: '#fff',
  },
  heroBadgeSubtitle: {
    fontSize: 11,
    color: '#f0e6ef',
  },
  section: {
    gap: 20,
  },
  sectionHeader: {
    gap: 8,
  },
  sectionOverline: {
    fontSize: 12,
    color: '#8b7486',
    textTransform: 'uppercase',
    letterSpacing: 1,
  },
  sectionTitle: {
    fontSize: 22,
    fontWeight: '700',
    color: '#2f1f2b',
  },
  sectionDescription: {
    fontSize: 13,
    color: '#6a566a',
    lineHeight: 20,
  },
  cardGrid: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 18,
  },
  cardGridStacked: {
    flexDirection: 'column',
  },
  card: {
    flexBasis: '48%',
    borderRadius: 24,
    backgroundColor: '#fff',
    borderWidth: 1,
    borderColor: 'rgba(220,195,208,0.4)',
    overflow: 'hidden',
    elevation: 4,
  },
  cardFull: {
    flexBasis: '100%',
  },
  cardThird: {
    flexBasis: '31%',
  },
  mediaBox: {
    position: 'relative',
    width: '100%',
    aspectRatio: 4 / 3,
    backgroundColor: '#f4e9f0',
    overflow: 'hidden',
  },
  cardImage: {
    width: '100%',
    height: '100%',
  },
  cardBody: {
    gap: 8,
    paddingHorizontal: 16,
    paddingVertical: 14,
  },
  cardTitle: {
    fontSize: 15,
    fontWeight: '600',
    color: '#2f1f2b',
  },
  cardType: {
    fontSize: 12,
    color: '#8b7486',
    fontWeight: '600',
  },
  cardDescription: {
    fontSize: 13,
    lineHeight: 18,
    color: '#6a566a',
  },
  priceBadge: {
    position: 'absolute',
    right: 10,
    bottom: 10,
    paddingHorizontal: 10,
    paddingVertical: 6,
    borderRadius: 999,
    backgroundColor: 'rgba(0,0,0,0.55)',
  },
  priceBadgeText: {
    color: '#fff',
    fontWeight: '700',
    fontSize: 12,
  },
  pricePromoText: {
    color: '#fff',
    fontWeight: '800',
    fontSize: 13,
  },
  priceOriginText: {
    color: 'rgba(255,255,255,0.8)',
    fontSize: 11,
    textDecorationLine: 'line-through',
  },
  promoBadge: {
    position: 'absolute',
    left: 10,
    top: 10,
    paddingHorizontal: 8,
    paddingVertical: 4,
    borderRadius: 999,
    backgroundColor: '#ff8fb1',
  },
  promoBadgeText: {
    color: '#2f1f2b',
    fontWeight: '700',
    fontSize: 11,
  },
  stateBox: {
    alignItems: 'center',
    gap: 10,
    paddingVertical: 24,
    paddingHorizontal: 18,
    borderRadius: 24,
    backgroundColor: 'rgba(255,143,177,0.08)',
  },
  stateBoxError: {
    backgroundColor: 'rgba(214,79,124,0.08)',
  },
  stateText: {
    fontSize: 13,
    color: '#6a566a',
  },
  stateTextDanger: {
    color: '#d64f7c',
  },
  retryButton: {
    paddingHorizontal: 18,
    paddingVertical: 10,
    borderRadius: 999,
    backgroundColor: '#ff8fb1',
  },
  retryButtonText: {
    fontSize: 13,
    fontWeight: '600',
    color: '#2f1f2b',
  },
  emptyState: {
    textAlign: 'center',
    paddingVertical: 12,
    borderRadius: 16,
    backgroundColor: 'rgba(255,143,177,0.14)',
    color: '#8b7486',
  },
  footer: {
    alignItems: 'center',
    gap: 6,
    paddingVertical: 16,
  },
  footerText: {
    fontSize: 12,
    color: '#8b7486',
  },
});






